package com.sunwayworld.basemodule.samplemanage.samplehandle.io;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.lowagie.text.BadElementException;
import com.sunwayworld.basemodule.basedata.exporttemplate.service.LimsGenericTemplateService;
import com.sunwayworld.basemodule.framework.utils.Bean2MapUtils;
import com.sunwayworld.basemodule.samplemanage.sample.bean.LimsSampleBean;
import com.sunwayworld.basemodule.samplemanage.sample.service.LimsSampleService;
import com.sunwayworld.basemodule.samplemanage.samplehandle.bean.LimsSampleHandleBean;
import com.sunwayworld.basemodule.samplemanage.samplehandle.service.LimsSampleHandleService;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.exception.InvalidDataException;
import com.sunwayworld.framework.io.file.FilePathDTO;
import com.sunwayworld.framework.io.file.FilePathManager;
import com.sunwayworld.framework.mybatis.mapper.MapperParameter;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.spring.annotation.GikamBean;
import com.sunwayworld.framework.utils.NumberUtils;
import com.sunwayworld.framework.utils.StringUtils;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

// 样本出库、返样、销毁单导出word模板类
@Component(value = "LimsSampleHandleExportDocxTemplate")
@GikamBean
public class LimsSampleHandleExportDocxTemplate implements LimsGenericTemplateService<String> {

    @Override
    public void initTemplateData(Path path, String id) {
        try {
            InputStream in = new FileInputStream(FilePathManager.getLocalPath(this.getTemplatePath()).toFile());

            LimsSampleHandleService handleService = ApplicationContextHelper.getBean(LimsSampleHandleService.class);
            if (StringUtils.isBlank(id)) {
                throw new InvalidDataException("数据存在异常，请检查！");
            }

            // 如果没带上样本编号顺序就按默认顺序来
            LimsSampleHandleBean handleBean = handleService.selectFirstByFilter(SearchFilter.instance().match("id", id).filter(MatchPattern.EQ));
            if (handleBean == null) {
                throw new InvalidDataException("数据存在异常，请检查！");
            }

            LimsSampleService sampleService = ApplicationContextHelper.getBean(LimsSampleService.class);
//            List<LimsSampleBean> sampleBeans = sampleService.selectHandleSample(NumberUtils.parseLong(id));

            MapperParameter parameter = new MapperParameter();
            parameter.setFilter(SearchFilter.instance().match("sampleHandleId", id).filter(MatchPattern.EQ));
            List<LimsSampleBean> sampleBeans = sampleService.selectSampleHandlesList(parameter);

            FileOutputStream fos = null;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            this.preBuildReport(in, handleBean, sampleBeans, bos);
            in.close();

            fos = new FileOutputStream(path.toFile());
            fos.write(bos.toByteArray());

            fos.close();
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void preBuildReport(InputStream reportInputStream, LimsSampleHandleBean handleBean, List<LimsSampleBean> sampleBeans, ByteArrayOutputStream bos) throws BadElementException, IOException {

        List<Map<String, Object>> mapList = new ArrayList<>();
        // 样本流转主bean转map
        Map<String, Object> resultMap = Bean2MapUtils.beanToMap(handleBean);

        if (handleBean.getCreatedTime() != null) {
            resultMap.put("createdTime", handleBean.getCreatedTime().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        }
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm"));
        resultMap.put("now", now);//当前日期

        List<ConcurrentHashMap> sampleList = new ArrayList<>();

        for (int i = 0; i < sampleBeans.size(); i++) {
            ConcurrentHashMap<String, String> row = new ConcurrentHashMap<>();
            row.put("index", String.valueOf(i + 1));
            row.put("sampleCode", sampleBeans.get(i).getSampleCode());
            row.put("sampleType", StringUtils.isBlank(sampleBeans.get(i).getSampleType()) ? "" : sampleBeans.get(i).getSampleType());
            // row.put("sampleSize", StringUtils.isBlank(sampleBeans.get(i).getSampleSize()) ? "" : sampleBeans.get(i).getSampleSize());
            row.put("locationdesc2", StringUtils.isBlank(sampleBeans.get(i).getExt$Item("locationdesc2")) ? "" : sampleBeans.get(i).getExt$Item("locationdesc2"));
            row.put("locations", StringUtils.isBlank(sampleBeans.get(i).getLocations()) ? "" : sampleBeans.get(i).getLocations());
            row.put("batchcode", StringUtils.isBlank(sampleBeans.get(i).getExt$Item("batchcode")) ? "" : sampleBeans.get(i).getExt$Item("batchcode"));
//                    if (sampleBeans.get(i).getCheckInTime() != null) {
//                        row.put("checkInTime", sampleBeans.get(i).getCheckInTime().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm")));
//                    } else {
//                        row.put("checkInTime", "");
//                    }
            sampleList.add(row);
        }
        resultMap.put("sampleList", sampleList);

        resultMap.put("tableData", mapList);

        ConfigureBuilder builder = Configure.newBuilder();
        builder.buildGramer("${", "}");
//        builder.addPlugin('@', new WordExportUtil.MyPictureRenderPolicy());
//        builder.bind("tableData", new HackLoopTableRenderPolicy());
//        builder.bind("mergeCellsVertically", new WordExportUtil.MergeCellsVertically());
        //builder.bind("resultFile", new PictureRender());图片插件
        Function<ConfigureBuilder, Map<String, Object>> renderDataCompute = configureBuilder -> resultMap;
        XWPFTemplate xwpfTemplate = XWPFTemplate.compile(reportInputStream, builder.build()).render(renderDataCompute.apply(builder));
        try {
            xwpfTemplate.write(bos);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                xwpfTemplate.close();
                resultMap.clear();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private FilePathDTO templatePath;

    @Override
    public void setTemplatePath(FilePathDTO templatePath) {
        this.templatePath = templatePath;
    }

    private FilePathDTO getTemplatePath() {
        return this.templatePath;
    }

    @Override
    public String getTemplateExtension() {
        return "docx";
    }
}
